# -*- coding: utf-8 -*-
import networkx as nx
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import json
import sys
from model import anagraphdistance
from math import sqrt

class GraphGenerator:
    def __init__(self, reshapeData = False, algorithm_type = 1):
        # set chinese font
        plt.rcParams['font.sans-serif']     = ['Microsoft YaHei']
        plt.rcParams['axes.unicode_minus']  = False

        # init variable
        self.__medicine_data    = []
        self.graph_obj          = nx.Graph()
        self.exportPath         = ''
        self.jaccard_gate       = 0
        self.reshapeData        = reshapeData
        self.ana_distance       = anagraphdistance.AnagraphDistance(algorithm_type)

    def __importData(self, data_list):
        self.__medicine_data = data_list
        if self.reshapeData:
            self.__medicine_data = self.__reshapeData(self.__medicine_data)
        # self.__cleanData()

    def __reshapeData(self, medicine_data):
        for item_ana in medicine_data:
            if item_ana.has_key('vector'):
                tmp_vector = np.array(item_ana['vector'])
                tmp_vector = tmp_vector.reshape(1, tmp_vector.size)
                item_ana['vector'] = list(tmp_vector[0])

        return medicine_data

    def __cleanData(self):
        vector_list     = [];
        cleaned_data    = []

        for item_data in self.__medicine_data:
            vector_tmp = json.dumps(item_data['vector'])

            if vector_tmp not in vector_list:
                vector_list.append(vector_tmp)
                cleaned_data.append(item_data)

        self.__medicine_data = cleaned_data

    def setDistanceGate(self, jaccard_gate):
        if jaccard_gate > 0:
            self.jaccard_gate = jaccard_gate

    def __getDistanceGate(self):
        return self.jaccard_gate

    def __setGraphNodes(self):
        for vector in self.__medicine_data:
            self.graph_obj.add_node(vector['name'])

    def __setClusterNodeEdges(self, cluster_node_list):
        name_list       = []
        distance_gate   = self.__getDistanceGate()
        # distance_gate = 1

        for vector_1 in self.__medicine_data:
            name_list.append(vector_1['name'])

            for vector_2 in self.__medicine_data:
                if vector_2['name'] not in name_list and vector_1['name'] in cluster_node_list and vector_2['name'] in cluster_node_list:
                        # get distance
                        distance = self.ana_distance.getRedisDistance(vector_1['name'], vector_2['name'])

                        # compare with distance gate
                        if distance < distance_gate:
                            self.graph_obj.add_edge(vector_1['name'], vector_2['name'], length = float(distance * 1))

    def generateDictGraph(self, data_list, cluster_dict):
        # import graph data
        self.__importData(data_list)
        # set nodes
        self.__setGraphNodes()

        for (ana_name, ana_list) in cluster_dict.items():
            if len(ana_list) > 0:
                # set cluster edges
                self.__setClusterNodeEdges(ana_list)

    def setExportPath(self, exportPath):
        if not exportPath:
            print 'Please make sure your exportPath is not empty.'+'\n'
        self.exportPath = exportPath

    def exportData(self):
        if not self.exportPath:
            print 'Please use setExportPath to set export data path.'+'\n'
        nx.write_gexf(self.graph_obj, self.exportPath)

    def displayGraph(self):
        nx.draw(self.graph_obj, node_color = 'r', with_labels = True, edge_color = 'black')
        plt.show()
